package com.offics.loan.infrastructure.persistence;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.offics.loan.domain.entity.RepaymentPlan;
import com.offics.loan.domain.repository.RepaymentPlanRepository;
import com.offics.loan.infrastructure.persistence.mapper.RepaymentPlanMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.time.LocalDate;
import java.util.List;
import java.util.Optional;

/**
 * 还款计划仓储实现类
 */
@Repository
@RequiredArgsConstructor
public class RepaymentPlanRepositoryImpl extends ServiceImpl<RepaymentPlanMapper, RepaymentPlan> implements RepaymentPlanRepository {

    private final RepaymentPlanMapper repaymentPlanMapper;

    @Override
    public Optional<RepaymentPlan> findById(Long id) {
        return Optional.ofNullable(repaymentPlanMapper.selectById(id));
    }

    @Override
    public List<RepaymentPlan> findByLoanId(Long loanId) {
        LambdaQueryWrapper<RepaymentPlan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentPlan::getLoanId, loanId);
        wrapper.orderByAsc(RepaymentPlan::getPeriod);
        return repaymentPlanMapper.selectList(wrapper);
    }

    @Override
    public List<RepaymentPlan> findByUserId(Long userId) {
        LambdaQueryWrapper<RepaymentPlan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentPlan::getUserId, userId);
        wrapper.orderByAsc(RepaymentPlan::getRepayDate);
        return repaymentPlanMapper.selectList(wrapper);
    }

    @Override
    public List<RepaymentPlan> findByUserIdAndStatus(Long userId, Integer status) {
        LambdaQueryWrapper<RepaymentPlan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentPlan::getUserId, userId);
        wrapper.eq(RepaymentPlan::getStatus, status);
        wrapper.orderByAsc(RepaymentPlan::getRepayDate);
        return repaymentPlanMapper.selectList(wrapper);
    }

    @Override
    public Optional<RepaymentPlan> findByLoanIdAndPeriod(Long loanId, Integer period) {
        LambdaQueryWrapper<RepaymentPlan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentPlan::getLoanId, loanId);
        wrapper.eq(RepaymentPlan::getPeriod, period);
        return Optional.ofNullable(repaymentPlanMapper.selectOne(wrapper));
    }

    @Override
    public List<RepaymentPlan> findUnpaidBeforeDate(LocalDate date) {
        LambdaQueryWrapper<RepaymentPlan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentPlan::getStatus, 0); // 未还
        wrapper.lt(RepaymentPlan::getRepayDate, date);
        return repaymentPlanMapper.selectList(wrapper);
    }

    @Override
    public IPage<RepaymentPlan> findPage(IPage<RepaymentPlan> page, Long userId, Long loanId, Integer status) {
        LambdaQueryWrapper<RepaymentPlan> wrapper = new LambdaQueryWrapper<>();
        if (userId != null) {
            wrapper.eq(RepaymentPlan::getUserId, userId);
        }
        if (loanId != null) {
            wrapper.eq(RepaymentPlan::getLoanId, loanId);
        }
        if (status != null) {
            wrapper.eq(RepaymentPlan::getStatus, status);
        }
        wrapper.orderByAsc(RepaymentPlan::getRepayDate);
        return repaymentPlanMapper.selectPage(page, wrapper);
    }

    @Override
    public boolean saveBatch(List<RepaymentPlan> repaymentPlans) {
        return saveBatch(repaymentPlans, 100);
    }

    @Override
    public boolean save(RepaymentPlan repaymentPlan) {
        return repaymentPlanMapper.insert(repaymentPlan) > 0;
    }

    @Override
    public RepaymentPlan saveAndReturn(RepaymentPlan repaymentPlan) {
        if (save(repaymentPlan)) {
            return repaymentPlan;
        }
        return null;
    }

    @Override
    public boolean update(RepaymentPlan repaymentPlan) {
        return repaymentPlanMapper.updateById(repaymentPlan) > 0;
    }

    @Override
    public boolean deleteById(Long id) {
        return repaymentPlanMapper.deleteById(id) > 0;
    }

    @Override
    public boolean deleteByLoanId(Long loanId) {
        LambdaQueryWrapper<RepaymentPlan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentPlan::getLoanId, loanId);
        return repaymentPlanMapper.delete(wrapper) > 0;
    }

    @Override
    public boolean deleteByUserId(Long userId) {
        LambdaQueryWrapper<RepaymentPlan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentPlan::getUserId, userId);
        return repaymentPlanMapper.delete(wrapper) > 0;
    }
}
